//
//  ASButtton-style.swift
//  SmoSky
//
//  Created by zhuxietong on 2018/7/5.
//  Copyright © 2018年 tianrun. All rights reserved.
//

import Foundation

import AsyncDisplayKit


public typealias ASButtonAction = (_ sender:Any)-> Void

public class ASButton: MoBaseNode {
    public let titleNode = ASTextNode2()
    public let button = ASButtonNode()
    public var padding:UIEdgeInsets = .zero
    
    public override func initStyle() {
    }
    public override func specGetter() -> _Spec {
//        let spec:_Spec = .wrapper(titleNode)
        let spec:_Spec = .wrapper(.inset([], padding, child: titleNode.Spec))
        return spec.addOver(button.Spec)
    }


}


open class MoButton:MoBaseNode{
    public enum Position {
        case left
        case right
        case top
        case bottom
    }
    
    
    public override init() {
        super.init()
    }
    
    public var imagePosition:Position = .left
    public var imageInset:UIEdgeInsets = .zero
    public var imageSize:CGSize = CGSize(width: 20.fs, height: 20)
    public var padding:UIEdgeInsets = .zero
    public var space:CGFloat = 4
    
    public let imageNode = ASImageNode()
    public let imageBackgroundNode = ASImageNode()

    public let titleNode = ASTextNode2()
    
    public let button = ASButtonNode()
    
    public var image:UIImage? = nil{
        didSet{
            imageNode.image = image
        }
    }
    public var attributedText:NSAttributedString?{
        set{
            titleNode.attributedText = newValue
        }
        get{
            return titleNode.attributedText
        }
    }
    
    open override func specGetter() -> _Spec {
        let w = imageSize.width
        let h = imageSize.height
        var spec:_Spec = .node(nil)
        var ls1:[_Spec] = [] //图片在前
        var ls2:[_Spec] = [] //图片在后
        
        if (image != nil)
        {
            ls1.append(.inset([], imageInset, child: imageNode[w,"\(h)"]))
        }
        if (attributedText != nil){
            ls1.append(titleNode[])
            ls2.append(titleNode[])
        }
        if (image != nil)
        {
            ls2.append(.inset([], imageInset, child: imageNode[w,"\(h)"]))
        }
        
        
        switch imagePosition {
        case .top:
            spec = .inset([], padding, child: .stack(["v|\(space)",&-.center,_justfy(.center),_nowrap], childs: ls1))
        case .bottom:
            spec = .inset([], padding, child: .stack(["v|\(space)",&-.center,_justfy(.center),_nowrap], childs: ls2))
        case .right:
            spec = .inset([], padding, child: .stack(["h|\(space)",&-.center,_justfy(.center),_nowrap], childs: ls2))
        case .left:
            spec = .inset([], padding, child: .stack(["h|\(space)",&-.center,_justfy(.center),_nowrap], childs: ls1))
        }
        return spec.addOver(button.Spec).addBack(imageBackgroundNode.Spec)
    }
}

extension ASButtonNode{
    
    
    final public var ui:ASButtonStyle{
        set{
            newValue.owner = self
            self.__style.setObject(newValue, forKey: "ui" as NSCopying)
        }
        get{
            if let st = self.__style.object(forKey: "ui") as? ASButtonStyle
            {
                st.owner = self
                return st
            }
            else
            {
                let style = ASButtonStyle()
                style.owner = self
                self.__style.setObject(style, forKey: "ui" as NSCopying)
                return style
            }
        }
    }
    
}



extension ASButtonNode
{
    public var __buttonColor: UIColor {
        set(newValue) {
            
            if let components = newValue.cgColor.components{
                
            
                var r:CGFloat = 0.5
                var g:CGFloat = 0.5
                var b:CGFloat = 0.5

                if components.count > 0{
                    r = components[0] * 0.7
                }
                if components.count > 1{
                    g = components[1] * 0.7
                }
                if components.count > 2{
                    b = components[2] * 0.7
                }
            
                let h_color = UIColor(red: r, green: g, blue: b, alpha: 1.0)
                self.setBackgroundImage(UIImage.image(newValue), for: .normal)
                self.setBackgroundImage(UIImage.image(h_color), for: .highlighted)
            
                self.layer.borderColor = newValue.cgColor
            }
        }
        get {
            return UIColor(cgColor: self.layer.borderColor!)
        }
    }
    
}

extension ASButtonNode{
    private struct __ButtonStyle {
        static var actionID = "ButtonStyleActionID"
    }
    
    public var actionID: String {
        get {
            if let ID = objc_getAssociatedObject(self, &__ButtonStyle.actionID) as? String
            {
                return ID
            }
            return ""
        }
        set {
            objc_setAssociatedObject(self,  &__ButtonStyle.actionID, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
}







public class ASButtonStyle:ASBaseStyle<ASButtonNode> {
    
    public enum ImagePosition{
        case left
        case right
    }
    
    
    
    var scolor:UIColor?
    var ncolor:UIColor?
    var ntitle:String?
    var stitle:String?
    
    var simage:UIImage?
    var nimage:UIImage?
    
    var padding:UIEdgeInsets?
    
    var imgPosition:ImagePosition = .left
    
    var font:UIFont?
    var buttonColor:UIColor?
    
    var touchUpInsideAction:ASButtonAction? = nil
    
    @objc func _touchUpInsideAction(sender:Any) {
        if let aciton = self.touchUpInsideAction{
            aciton(sender)
        }
    }
    
    public var actionID:String?
    
    public override init() {
    }
    
    public override func assign(to owner:ASButtonNode) -> ASButtonStyle {
        //        self.owner = owner
        owner.ui = self
        return self
    }
    
    
    public class func new() ->ASButtonStyle{
        
        return ASButtonStyle()
    }
    
    @discardableResult
    public func actionID(ID:String) ->ASButtonStyle{
        self.actionID = ID
        self.owner?.actionID = ID
        return self
    }
    
    @discardableResult
    public func touchUpInside(_ action:@escaping ASButtonAction) ->ASButtonStyle{
        self.touchUpInsideAction = action
        self.owner?.addTarget(self, action: #selector(_touchUpInsideAction(sender:)), forControlEvents: .touchUpInside)
        return self
    }
    
    
    @discardableResult
    public func buttonColor(hex:String) ->ASButtonStyle
    {
        
        self.buttonColor = UIColor(shex: hex)
        self.owner?.__buttonColor = self.buttonColor!
        return self
    }
    
    @discardableResult
    public func buttonColor(color:UIColor) ->ASButtonStyle
    {
        self.buttonColor = color
        self.owner?.__buttonColor = self.buttonColor!
        return self
    }
    
    
    @discardableResult
    public func ncolor(hex:String) ->ASButtonStyle
    {
        let color = UIColor(shex: hex)
        self.ncolor =  color
        if let attrs = self.owner?.attributedTitle(for: .normal)
        {
            let new_atrrs = NSMutableAttributedString(attributedString: attrs)

            new_atrrs.addAttributes([NSAttributedString.Key.foregroundColor:color], range: NSMakeRange(0, new_atrrs.length))
            owner?.setAttributedTitle(new_atrrs, for: .normal)
        }
        
        return self
    }
    @discardableResult
    public func scolor(hex:String) ->ASButtonStyle
    {
        self.scolor = UIColor(shex: hex)
        let color = UIColor(shex: hex)
        self.ncolor =  color
        
        var title = self.owner?.attributedTitle(for: .normal)
        if let attrs = self.owner?.attributedTitle(for: .selected)
        {
            title = attrs
        }
        
        if let attrs = title
        {
            let new_atrrs = NSMutableAttributedString(attributedString: attrs)
            new_atrrs.addAttributes([NSAttributedString.Key.foregroundColor:color], range: NSMakeRange(0, new_atrrs.length))
            owner?.setAttributedTitle(new_atrrs, for: .selected)
        }

        
        return self
    }
    
    
    @discardableResult
    public func ncolor(color:UIColor) ->ASButtonStyle
    {
        self.ncolor = color
        self.ncolor =  color
        if let attrs = self.owner?.attributedTitle(for: .normal)
        {
            let new_atrrs = NSMutableAttributedString(attributedString: attrs)
            
            new_atrrs.addAttributes([NSAttributedString.Key.foregroundColor:color], range: NSMakeRange(0, new_atrrs.length))
            owner?.setAttributedTitle(new_atrrs, for: .normal)
        }
        return self
    }
    
    @discardableResult
    public func scolor(color:UIColor) ->ASButtonStyle
    {
        self.scolor = color
        var title = self.owner?.attributedTitle(for: .normal)
        if let attrs = self.owner?.attributedTitle(for: .selected)
        {
            title = attrs
        }
        
        if let attrs = title
        {
            let new_atrrs = NSMutableAttributedString(attributedString: attrs)
            new_atrrs.addAttributes([NSAttributedString.Key.foregroundColor:color], range: NSMakeRange(0, new_atrrs.length))
            owner?.setAttributedTitle(new_atrrs, for: .selected)
        }
        return self
    }
    @discardableResult
    public func ntitle(title:String) ->ASButtonStyle
    {
        self.ntitle = title
        self.actionID = title
        self.owner?.actionID = title
        var atrrs = [NSAttributedString.Key:Any]()
        if let font = self.font
        {
            atrrs[NSAttributedString.Key.font] = font;
        }
        
        if let color = self.ncolor
        {
            atrrs[NSAttributedString.Key.foregroundColor] = color;
        }
        let titleAtrr = NSMutableAttributedString(string: title, attributes:atrrs)
        
        owner?.setAttributedTitle(titleAtrr, for: .normal)
        

        return self
    }
    @discardableResult
    public func stitle(title:String) ->ASButtonStyle
    {
        self.stitle = title
        self.actionID = title
        self.owner?.actionID = title

        var atrrs = [NSAttributedString.Key:Any]()
        if let font = self.font
        {
            atrrs[NSAttributedString.Key.font] = font;
        }
        
        if let color = self.scolor
        {
            atrrs[NSAttributedString.Key.foregroundColor] = color;
        }
        let titleAtrr = NSMutableAttributedString(string: title, attributes:atrrs)
        
        owner?.setAttributedTitle(titleAtrr, for: .selected)
        return self
    }
    
    @discardableResult
    public func font(font:UIFont) -> ASButtonStyle{
        self.font = font
        if let attrs = self.owner?.attributedTitle(for: .selected)
        {
            let new_atrrs = NSMutableAttributedString(attributedString: attrs)
            new_atrrs.addAttributes([NSAttributedString.Key.font:font], range: NSMakeRange(0, new_atrrs.length))
            owner?.setAttributedTitle(new_atrrs, for: .selected)
            
        }
        if let attrs = self.owner?.attributedTitle(for: .normal)
        {
            let new_atrrs = NSMutableAttributedString(attributedString: attrs)
            new_atrrs.addAttributes([NSAttributedString.Key.font:font], range: NSMakeRange(0, new_atrrs.length))
            owner?.setAttributedTitle(new_atrrs, for: .normal)
            
        }
       return self
    }
    
    @discardableResult
    public func font(size:CGFloat) -> ASButtonStyle{
        
        let font = UIFont.systemFont(ofSize: size.fs)
        self.font = font
        if let attrs = self.owner?.attributedTitle(for: .selected)
        {
            let new_atrrs = NSMutableAttributedString(attributedString: attrs)
            new_atrrs.addAttributes([NSAttributedString.Key.font:font], range: NSMakeRange(0, new_atrrs.length))
            owner?.setAttributedTitle(new_atrrs, for: .selected)
            
        }
        if let attrs = self.owner?.attributedTitle(for: .normal)
        {
            let new_atrrs = NSMutableAttributedString(attributedString: attrs)
            new_atrrs.addAttributes([NSAttributedString.Key.font:font], range: NSMakeRange(0, new_atrrs.length))
            owner?.setAttributedTitle(new_atrrs, for: .normal)
            
        }
        return self
    }
    @discardableResult
    public func bfont(size:CGFloat) -> ASButtonStyle{
        let font = UIFont.boldSystemFont(ofSize: size.fs)
        self.font = font
        if let attrs = self.owner?.attributedTitle(for: .selected)
        {
            let new_atrrs = NSMutableAttributedString(attributedString: attrs)
            new_atrrs.addAttributes([NSAttributedString.Key.font:font], range: NSMakeRange(0, new_atrrs.length))
            owner?.setAttributedTitle(new_atrrs, for: .selected)
            
        }
        if let attrs = self.owner?.attributedTitle(for: .normal)
        {
            let new_atrrs = NSMutableAttributedString(attributedString: attrs)
            new_atrrs.addAttributes([NSAttributedString.Key.font:font], range: NSMakeRange(0, new_atrrs.length))
            owner?.setAttributedTitle(new_atrrs, for: .normal)
            
        }
        return self
    }
    
    @discardableResult
    public func mfont(size:CGFloat) -> ASButtonStyle{
        let font = UIFont.systemFont(ofSize: size.fs, weight: .medium)
        self.font = font
        if let attrs = self.owner?.attributedTitle(for: .selected)
        {
            let new_atrrs = NSMutableAttributedString(attributedString: attrs)
            new_atrrs.addAttributes([NSAttributedString.Key.font:font], range: NSMakeRange(0, new_atrrs.length))
            owner?.setAttributedTitle(new_atrrs, for: .selected)
            
        }
        if let attrs = self.owner?.attributedTitle(for: .normal)
        {
            let new_atrrs = NSMutableAttributedString(attributedString: attrs)
            new_atrrs.addAttributes([NSAttributedString.Key.font:font], range: NSMakeRange(0, new_atrrs.length))
            owner?.setAttributedTitle(new_atrrs, for: .normal)
            
        }
        return self
    }
    
  
    @discardableResult
    public func simage(_ image:UIImage?) -> ASButtonStyle{
        self.simage = image
        self.owner?.setImage(image, for: .selected)
        
        return self
    }
    
    @discardableResult
    public func nimage(_ image:UIImage?) -> ASButtonStyle{
        if self.simage == nil
        {
            self.simage(nimage)
        }
        self.nimage = image
        self.owner?.setImage(image, for: .normal)
        return self
    }
    
    @discardableResult
    public func padding(insets:UIEdgeInsets?) -> ASButtonStyle{
        self.padding = insets
        if let pd = self.padding{
            self.owner?.contentEdgeInsets = pd
        }
        return self
    }
    
    
    @discardableResult
    public func hidden(hidden:Bool) -> ASButtonStyle{
        self.isHidden = hidden
        self.owner?.isHidden = self.isHidden
        return self
    }

    
    public override func run() {
        
        
        self.owner?.actionID = self.actionID ?? ""
        if let sc = self.scolor
        {
            self.scolor(color: sc)
        }
        if let nc = self.ncolor
        {
            self.ncolor(color: nc)
        }
        if let nt = self.ntitle
        {
            self.ntitle(title: nt)
        }
        if let st = self.stitle
        {
            self.ntitle(title: st)
        }
        if let f = self.font
        {
            self.font(font: f)
        }
        if let bc = self.buttonColor
        {
            self.buttonColor(color: bc)
        }
        
        if let nimg = self.nimage{
            self.nimage(nimg)
        }
        if let simg = self.simage{
            self.simage(simg)
        }
        if let pd = self.padding
        {
            self.padding(insets: pd)
        }

        super.run()
        
        
        
    }
    
    
    
}


